﻿using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roulette
{
    /// <summary>
    /// Describes a possible outcome
    /// </summary>
    public class Outcome
    {
        public double Probability { get; set; }
        /// <summary>
        /// Gain relative to the total cash disponible (ie. 0.1d = 10%)
        /// </summary>
        public double Gain { get; set; }

        #region Object methods overridings and operators
        public override bool Equals(object value)
        {
            var type = value as Outcome;
            return ((!ReferenceEquals(null, type))
                && this.Probability.Equals(type.Probability)
                && this.Gain.Equals(type.Gain));
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int num = -1134271262;
                num = (-1521134295 * num) + this.Probability.GetHashCode();
                return ((-1521134295 * num) + this.Gain.GetHashCode());
            }
        }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.Append("{ Probability = ");
            builder.Append(this.Probability);
            builder.Append(", Gain = ");
            builder.Append(this.Gain);
            builder.Append(" }");
            return builder.ToString();
        }

        public static bool operator ==(Outcome outcomeA, Outcome outcomeB)
        {
            if (ReferenceEquals(null, outcomeA)) return ReferenceEquals(null, outcomeB);
            return outcomeA.Equals(outcomeB);
        }

        public static bool operator !=(Outcome outcomeA, Outcome outcomeB)
        {
            return !(outcomeA == outcomeB);
        }
        #endregion

        public Outcome()
        {
            this.Probability = 1d;
            this.Gain = 0d;
        }

        public static IEnumerable<Outcome> GroupByGain(IEnumerable<Outcome> outcomes)
        {
            return outcomes
                .GroupBy(outcome => outcome.Gain)
                .Select(group => new Outcome()
                {
                    Gain = group.Key,
                    Probability = group.Sum(outcome => outcome.Probability)
                });
        }
    }
}
